/**
 * @file mobjbuf_ts.h
 *
 * @author yhuan416<yhuan416@foxmail.com>
 * @date 2025-10-03
 *
 * @brief 线程安全的 mobjbuf 包装器
 *          通过外部传递的临界区保护函数实现线程安全
 *
 * @note 线程安全部分保持相对独立，不修改原有 mobjbuf 代码
 */
#ifndef __mobjbuf_ts_h__
#define __mobjbuf_ts_h__

#include "mobjbuf.h"

#ifdef __cplusplus__
extern "C" {
#endif

/**
 * @brief 临界区保护函数类型
 *
 * @param userdata 用户数据指针
 * @param is_lock true: 加锁, false: 解锁
 */
typedef void (*mobjbuf_ts_lock_fn)(void *userdata, bool is_lock);

/**
 * @brief 线程安全的内存池管理器
 */
typedef struct
{
    mobjbuf_t objbuf;                    // 基础内存池对象
    mobjbuf_ts_lock_fn lock_fn;          // 临界区保护函数
    void *lock_userdata;                 // 临界区保护函数用户数据
} mobjbuf_ts_t;

/**
 * @brief 初始化线程安全内存池
 *
 * @param ts_objbuf 线程安全内存池对象
 * @param buffer 外部传入的缓冲区
 * @param buf_size 缓冲区大小
 * @param lock_fn 临界区保护函数
 * @param lock_userdata 临界区保护函数用户数据
 *
 * @return 0: 成功, -1: 失败
 */
extern int mobjbuf_ts_init(mobjbuf_ts_t *ts_objbuf,
                          void *buffer,
                          size_t buf_size,
                          mobjbuf_ts_lock_fn lock_fn,
                          void *lock_userdata);

/**
 * @brief 线程安全分配内存
 *
 * @param ts_objbuf 线程安全内存池对象
 * @param size 需要的大小
 * @param discard_callback 逐出回调函数
 * @param userdata 用户数据指针
 *
 * @return 分配的内存指针，失败则返回NULL
 */
extern void *mobjbuf_ts_alloc(mobjbuf_ts_t *ts_objbuf,
                             size_t size,
                             mobjbuf_discard_callback_fn discard_callback,
                             void *userdata);

/**
 * @brief 线程安全释放内存
 *
 * @param ts_objbuf 线程安全内存池对象
 * @param ptr 要释放的内存指针
 */
extern void mobjbuf_ts_free(mobjbuf_ts_t *ts_objbuf, void *ptr);

/**
 * @brief 线程安全释放内存（不合并空闲块）
 *
 * @param ts_objbuf 线程安全内存池对象
 * @param ptr 要释放的内存指针
 */
extern void mobjbuf_ts_free_without_merge(mobjbuf_ts_t *ts_objbuf, void *ptr);

/**
 * @brief 线程安全合并所有空闲块
 *
 * @param ts_objbuf 线程安全内存池对象
 */
extern void mobjbuf_ts_merge_free_blocks(mobjbuf_ts_t *ts_objbuf);

/**
 * @brief 线程安全打印内存池信息
 *
 * @param ts_objbuf 线程安全内存池对象
 */
extern void mobjbuf_ts_dump(mobjbuf_ts_t *ts_objbuf);

#ifdef __cplusplus__
}
#endif

#endif /* __mobjbuf_ts_h__ */